﻿/*
 * !!! Устаревший !!! Пример работы с подсистемой моделирования из приложения.
 * */
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

using ctem.kernel;
using ctem.kernel.lib;
using ctem.samples.actors.sequential;
using ctem.samples.actors.concurrent;
using ctem.kernel.adbms;
using ctem.kernel.logger;


namespace ctem.samples.kernelcstest
{
    class Program
    {
        static void Main(string[] args)
        {
            
            //создаём моделлер - моделлер, это посути дела синглетон через который 
            //осуществляется асинхронный обмен командами с подсистемой моделирования
            //нужена ли синхронная посылка команд пока не понятно
            //запросить у подсистемы моделирования какое-либо значение пока тоже нельзя
            IModeller modeller = ctem.kernel.adbms.ModellerService.QueryModellerService("D:\\_RES\\");
            
            //команда, полный синтаксис всего множества команд пока не приведен(да и не определен)
            //части команды, должы быть разделены проблелами
            //несколько пробелов подряд допускается
            //если необходимо использовать пробелы внутри части команды(нпр. при задании пути), то
            //необходимо заключить эту часть в одинарные ковычки

            //кроме создания нового актора, запуска и остановки моделирования больше ничего сделать
            //нельзя. Связи между акторами создаваить нельзя. (к этому все уже готово, просто
            //не хватило времени, да и есть некоторые шероховатости в дизайне)
            //параллельная работа актора тоже не реализована(для этого будет введен доп. тип актора)

            //путь до сборки с актором
            string param1 = @"'D:\Documents and Settings\AV\Мои документы\_Projects\_CTEM\Code\ctem.samples\ctem.samples.actors.sequential\bin\Debug\ctem.samples.actors.sequential.dll'";
            //полное имя типа актора
            string param2 = "ctem.samples.actors.sequential.IncActor";
            //имя актора, через которое к нему в последующем можно будет обратиться
            string param3 = "IncActorName";
            //modeller.AsyncSendCommand("new actor" + " " + " " + param1 + " " + param2 + " " + param3);

            param2 = "ctem.samples.actors.sequential.ConsoleActor";
            param3 = "PrintingActor";
            //modeller.AsyncSendCommand("new actor" + " " + " " + param1 + " " + param2 + " " + param3);

            param2 = "ctem.samples.actors.sequential.OneStepGenerator";
            param3 = "OneStepGenerator";
            modeller.AsyncSendCommand("new actor" + " " + " " + param1 + " " + param2 + " " + param3);

            param2 = "ctem.samples.actors.sequential.SinGenerator";
            param3 = "SinGenerator";
            modeller.AsyncSendCommand("new actor" + " " + " " + param1 + " " + param2 + " " + param3);

            param2 = "ctem.samples.actors.sequential.Booster";
            param3 = "Booster";
            modeller.AsyncSendCommand("new actor" + " " + " " + param1 + " " + param2 + " " + param3);

            param1 = @"'D:\Documents and Settings\AV\Мои документы\_Projects\_CTEM\Code\ctem.samples\ctem.samples.actors.concurrent\bin\Debug\ctem.samples.actors.concurrent.dll'";
            param2 = "ctem.samples.actors.concurrent.ConcurActor";
            param3 = "ConcurActor";
            modeller.AsyncSendCommand("new actor" + " " + " " + param1 + " " + param2 + " " + param3);

            param1 = @"'D:\Documents and Settings\AV\Мои документы\_Projects\_CTEM\Code\ctem.samples\ctem.samples.actors.concurrent\bin\Debug\ctem.samples.actors.concurrent.dll'";
            param2 = "ctem.samples.actors.concurrent.ConcurActor";
            param3 = "ConcurActor2";
            modeller.AsyncSendCommand("new actor" + " " + " " + param1 + " " + param2 + " " + param3);

            /*param1 = "SeqGenerator.outport";
            param2 = "IncActorName.inport";
            modeller.AsyncSendCommand("new link" + " " + " " + param1 + " " + param2 );
            */
            param1 = "OneStepGenerator.outport";
            param2 = "Booster.inport";
            modeller.AsyncSendCommand("new link" + " " + " " + param1 + " " + param2);

            param1 = "Booster.outport";
            param2 = "ConcurActor.inport";
            modeller.AsyncSendCommand("new link" + " " + " " + param1 + " " + param2);

            param1 = "SinGenerator.outport";
            param2 = "ConcurActor2.inport";
            modeller.AsyncSendCommand("new link" + " " + " " + param1 + " " + param2);

            modeller.AsyncSendCommand("set param Booster.k 10,0");


            Console.WriteLine("START");
            modeller.AsyncSendCommand("start");

            //Console.WriteLine(modeller.SyncSendCommand<double>("get param PrintingActor.super_param"));

            modeller.SyncSendCommand<ILogger>("get logger TEST").WriteMessage(MessagePriority.Debug, "get logger TEST - OK");


            
/*
            //если использовать Thread.Sleep(...), то почему-то прекращается вывод в консоль
            //из других потоков, поэтому с помощью цикла имитирую задержку
            //сейчас делаю потокобезопасную обертку над логгером, тогда консоль вообще можно будет 
            //не использовать
            for (int i = 0; i < 1000000; i++) { for (int j = 0; j < 1000; j++) { bool b = 1.0 > 2.0; } }
            Console.WriteLine("PAUSE");
            modeller.AsyncSendCommand("pause");

            for (int i = 0; i < 1000000; i++) { for (int j = 0; j < 1000; j++) { bool b = 1.0 > 2.0; } }
            Console.WriteLine("UNPAUSE");
            modeller.AsyncSendCommand("unpause");
*/
            while (true)
            {
                
                modeller.AsyncSendCommand("set param SeqGenerator.state " + Console.ReadLine());
            }

            //ниже старый код - он нужен мне для тестов, но компилироваться у тебя он не будет,
            //так что не обращай на него внимания
           // GraphLib.Graph<IActor, ILink> graph = new GraphLib.Graph<IActor, ILink>();
            
            
            //IncActor inc1 = new IncActor("inc1");
            //foreach (IPort port in inc1.GetInPorts()) port.SetGraph(graph);
            //foreach (IPort port in inc1.GetOutPorts()) port.SetGraph(graph);

            //IncActor inc2 = new IncActor("inc2");
            //foreach (IPort port in inc2.GetInPorts()) port.SetGraph(graph);
            //foreach (IPort port in inc2.GetOutPorts()) port.SetGraph(graph);

            //ConsoleActor vizactor = new ConsoleActor("ConsoleActor3");
            //foreach (IPort port in vizactor.GetInPorts()) port.SetGraph(graph);
            //foreach (IPort port in vizactor.GetOutPorts()) port.SetGraph(graph);

            //SeqGenerator gen = new SeqGenerator("SeqGenerator4");
            //foreach (IPort port in gen.GetInPorts()) port.SetGraph(graph);
            //foreach (IPort port in gen.GetOutPorts()) port.SetGraph(graph);

            //graph.AddVertex(gen);
            //graph.AddVertex(inc1);
            //graph.AddVertex(inc2);
            //graph.AddVertex(vizactor);
            
            //Link link0 = new Link(gen.GetOutPortByName("outport"), inc1.GetInPortByName("inport"));
            //Link link1 = new Link(inc1.GetOutPortByName("outport"), vizactor.GetInPortByName("inport"));
            //Link link2 = new Link(inc2.GetOutPortByName("outport"), vizactor.GetInPortByName("inport"));
            //Link link3 = new Link(gen.GetOutPortByName("outport"), inc2.GetInPortByName("inport"));

            //graph.AddEdge(link0);
            //graph.AddEdge(link1);
            //graph.AddEdge(link2);
            //graph.AddEdge(link3);
        }

        
    }
}
